home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
utils
/
sort.arc
/
sortfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-30
|
8KB
|
279 lines
/******************************************************************************
* *
* sortfile.c version 1.0 of 1 Januari 1989 (C) L.J.M. de Wit 1989 *
* *
* This software may be used and distributed freely if not used commercially *
* and the originator (me) is mentioned in the source (just leave this 9 line *
* header intact). *
* *
******************************************************************************
*
* sortfile.c: stdio replacement for Atari ST
*
* This replacement is added both to speed up the normal stdio offered by
* Lattice C, and to repair a bug with open() (fopen() ?) that is in the
* standard library (version 3.03: try opening & closing 20 files, your
* program bombs when you try to open a new file, even though the old ones
* have been closed).
*
* Note that this package is not complete (no flushbuf, filbuf, printf etc.)
* but this wasn't the intent anyway; furthermore, the allocation of buffers
* takes place when a file is opened, rather than when it is first read/written
* (as in a standard stdio package).
*/
#include <stdio.h>
#include <osbind.h>
#include <fcntl.h>
#include "sortmain.h"
#include "sortfile.h"
#undef Fwrite
#define Fwrite fixwrite /* Fix for Fwrite bug */
static int buflen; /* Default buffer length */
static int lopen();
static int fixwrite();
#ifdef BESTIO
void bestio(size) /* Initializes stdin/stdout */
int size;
{
char *iobuffer[2]; /* stdin/stdout buffer ptrs */
buflen = size;
iobuffer[0] = (char *)Malloc(buflen);
iobuffer[1] = (char *)Malloc(buflen);
if (iobuffer[0] == (char *)-1 || iobuffer[1] == (char *)-1) {
error("memory allocation failed\n",(char *)0);
}
stdin->_ptr = stdin->_base = iobuffer[0];
stdin->_rcnt = buflen;
stdin->_flag = _IOREAD;
stdin->_file = 0;
stdin->_size = buflen;
stdout->_ptr = stdout->_base = iobuffer[1];
stdout->_wcnt = buflen;
stdout->_flag = _IOWRT;
stdout->_file = 1;
stdout->_size = buflen;
}
void exit(code) /* Replaces standard exit */
int code;
{
int i;
for (i = 0; i < _NFILE; i++) {
if (_iob[i]._flag != 0) { /* Stclose any open files */
stclose(_iob+i);
}
}
_exit(code); /* and _exit */
}
#else NOT BESTIO
int _fmode = 0x8000; /* No translation, for speed*/
#endif BESTIO
FILE *stopen(filename,mode) /* Replaces fopen() */
char *filename, *mode;
{
FILE *fp;
int desc;
int flag;
int i;
for (i = 0; i < _NFILE; i++) { /* Find first free entry */
if (_iob[i]._flag == 0) {
break;
}
}
if (i < _NFILE) {
fp = _iob + i; /* First free */
} else {
return (FILE *)0; /* All occupied */
}
if (!strcmp(mode,"w")) { /* Mode "w": write */
desc = lopen(filename,O_WRONLY|O_CREAT|O_TRUNC);
flag = _IOWRT;
} else if (!strcmp(mode,"r")) { /* Mode "r": read */
desc = lopen(filename,O_RDONLY);
flag = _IOREAD;
} else { /* Unknown mode */
return (FILE *)0;
}
if (desc < 0) {
return (FILE *)0; /* Lopen failed */
} else {
fp->_rcnt = fp->_wcnt = fp->_size = 0;
fp->_ptr = fp->_base = (char *)0;
fp->_file = desc;
fp->_flag = flag;
}
return fp;
}
int stclose(fp) /* Replaces fclose() */
FILE *fp;
{
int retco;
if (fp->_flag & (_IORW|_IOWRT)) {
stflush(fp); /* Flush an output stream */
}
retco = Fclose(fp->_file); /* Close file */
if (fp->_base != (char *)0) {
retco |= Mfree(fp->_base); /* Free allocated buffer */
}
fp->_base = (char *)0;
fp->_flag = 0; /* Indicate entry is free */
return retco;
}
int stflush(fp)
FILE *fp;
{
if (fp->_size > fp->_wcnt) { /* Any data to be flushed ? */
Fwrite(fp->_file,fp->_size-fp->_wcnt,fp->_base); /* Write it */
fp->_ptr = fp->_base; /* re-init ptr */
fp->_wcnt = fp->_size; /* and _wcnt */
}
}
void stbuffer(fp,buf,size)
FILE *fp;
char *buf;
int size;
{
fp->_ptr = fp->_base = buf;
fp->_size = size;
fp->_wcnt = size;
fp->_rcnt = 0;
}
char *stgets(inbuf,size,fp) /* Replaces fgets() */
char *inbuf;
register int size;
register FILE *fp;
{
register int todo, i, ntoread;
register char *s, *t;
if (fp->_base == (char *)0) {
s = (char *)Malloc(buflen); /* Allocate buffer */
stbuffer(fp,s,buflen);
}
if (size-- <= 0 || feof(fp)) { /* One for the '\0' */
return (char *)0;
}
t = inbuf;
s = fp->_ptr;
ntoread = fp->_rcnt;
for ( ; ; ) {
todo = min(size,ntoread);
for (i = 0; i < todo; i++) {
if ((*t++ = *s++) == '\n') { /* Had a newline */
i++;
*t = '\0'; /* 0-terminate line */
fp->_ptr = s;
fp->_rcnt = ntoread - i;
return inbuf;
}
}
if ((size -= todo) <= 0) { /* All read */
break;
}
ntoread = Fread(fp->_file,fp->_size,fp->_base); /* Read a buffer */
s = fp->_base; /* Re-init ptr */
if (ntoread <= 0) {
fp->_flag |= _IOEOF;
return (char *)0; /* End-of-file */
}
}
fp->_rcnt = ntoread - todo;
fp->_ptr = s;
*t = '\0';
return inbuf;
}
void stputs(inbuf,fp) /* Replaces fputs() */
char *inbuf;
register FILE *fp;
{
register int i, ntowrite;
register char *s, *t;
if (fp->_base == (char *)0) {
s = (char *)Malloc(buflen); /* Allocate buffer */
stbuffer(fp,s,buflen);
}
s = inbuf;
t = fp->_ptr;
ntowrite = fp->_wcnt;
for ( ; ; ) {
for (i = 0; i < ntowrite; i++) {
if (*s == '\0') { /* Found 0 terminator */
break;
}
*t++ = *s++;
}
if (*s == '\0') {
fp->_wcnt = ntowrite - i;
fp->_ptr = t;
return;
}
Fwrite(fp->_file,t - fp->_base,fp->_base); /* Write a buffer */
ntowrite = fp->_size;
t = fp->_base; /* Re-init ptr */
}
}
static int lopen(filename,mode) /* Simple open() replacement*/
char *filename;
int mode;
{
int fd;
if (!(mode & O_TRUNC)) {
fd = Fopen(filename,mode & (O_WRONLY|O_RDWR)); /* Open file */
}
if ((mode & O_TRUNC) || ((fd < 0) && (mode & O_CREAT))) {
fd = Fcreate(filename,!(mode & (O_WRONLY|O_RDWR))); /* Create file */
}
return fd;
}
static int fixwrite(fd,len,buf)
int fd, len;
char *buf;
{
int total, piece = 0;
char *top;
if (fd != 1) {
return gemdos(0x40,fd,len,buf);
}
for (total = 0, top = buf + len; len > 0; buf += piece, len -= piece) {
if ((piece = len) > 32767) {
piece = 32256;
}
total += gemdos(0x40,fd,pi